package com.tky.utils;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.IOException;
import java.io.InputStream;
import java.util.HashMap;
import java.util.Map;
import java.util.Properties;
import java.util.Set;

/**
 * 用于从类路径中的配置文件读取配置属性的工具类。
 * 提供加载所有属性或获取指定键值的方法。
 */
public class PropertiesReader {

    private static final Logger logger = LoggerFactory.getLogger(PropertiesReader.class);

    /**
     * 从指定配置文件加载所有属性到 Map 中。
     * 配置文件必须位于类路径中（例如 src/main/resources）。
     *
     * @param filePath 配置文件路径（例如 "config.properties"）
     * @return 包含所有键值对的 {@link Map} 对象
     * @throws IllegalArgumentException 如果 filePath 为空或文件无法加载
     *
     *                                  <p><b>使用示例：</b></p>
     *                                  <pre>
     *                                                                                                        Map<String, String> config = PropertiesReader.loadAllProperties("config.properties");
     *                                                                                                        System.out.println(config.get("database.url")); // 输出 database.url 的值
     *                                                                                                    </pre>
     */
    public static Map<String, String> loadAllProperties(String filePath) {
        if (filePath == null || filePath.trim().isEmpty()) {
            logger.error("配置文件路径为空或无效");
            throw new IllegalArgumentException("配置文件路径不能为空或空字符串");
        }

        Properties properties = loadPropertiesFile(filePath);
        Map<String, String> result = new HashMap<>(properties.size());

        for (String key : properties.stringPropertyNames()) {
            result.put(key, properties.getProperty(key));
        }

        if (result.isEmpty()) {
            logger.warn("配置文件 {} 中未找到任何属性", filePath);
        }

        return result;
    }

    /**
     * 从指定配置文件中获取指定键的属性值。
     * 配置文件必须位于类路径中（例如 src/main/resources）。
     *
     * @param key      要查询的键
     * @param filePath 配置文件路径（例如 "config.properties"）
     * @return 键对应的值，若键或文件不存在则返回 null
     * @throws IllegalArgumentException 如果 key 或 filePath 为空或无效
     *
     *                                  <p><b>使用示例：</b></p>
     *                                  <pre>
     *
     *                                                                                                        String dbUrl = PropertiesReader.getPropertyByKey("database.url", "config.properties");
     *                                                                                                        if (dbUrl != null) {
     *                                                                                                            System.out.println("数据库 URL: " + dbUrl);
     *                                                                                                        } else {
     *                                                                                                            System.out.println("键不存在或文件无法访问");
     *                                                                                                        }
     *
     *                                                                                                    </pre>
     */
    public static String getPropertyByKey(String key, String filePath) {
        if (key == null || key.trim().isEmpty()) {
            logger.error("键值为空或无效");
            throw new IllegalArgumentException("键值不能为空或空字符串");
        }
        if (filePath == null || filePath.trim().isEmpty()) {
            logger.error("配置文件路径为空或无效");
            throw new IllegalArgumentException("配置文件路径不能为空或空字符串");
        }

        Properties properties = loadPropertiesFile(filePath);
        String value = properties.getProperty(key);

        if (value == null) {
            logger.warn("在配置文件 {} 中未找到键 '{}'", filePath, key);
        }

        return value;
    }

    /**
     * 加载类路径中的配置文件。
     *
     * @param filePath 配置文件路径
     * @return 包含加载属性的 {@link Properties} 对象
     * @throws IllegalArgumentException 如果文件无法加载
     */
    private static Properties loadPropertiesFile(String filePath) {
        Properties properties = new Properties();
        try (InputStream inputStream = PropertiesReader.class.getClassLoader().getResourceAsStream(filePath)) {
            if (inputStream == null) {
                logger.error("配置文件未找到：{}", filePath);
                throw new IllegalArgumentException("配置文件未找到：" + filePath);
            }
            properties.load(inputStream);
        } catch (IOException e) {
            logger.error("加载配置文件 {} 失败，错误：{}", filePath, e.getMessage(), e);
            throw new IllegalArgumentException("加载配置文件失败：" + filePath, e);
        }
        return properties;
    }

    public static void main(String[] args) {
        try {
            // 获取指定键的值
            String hbaseQuorum = PropertiesReader.getPropertyByKey("hbase.zookeeper.quorum", "config.properties");
            if (hbaseQuorum != null) {
                System.out.println("HBase Zookeeper Quorum: " + hbaseQuorum);
            } else {
                System.out.println("键不存在或文件无法访问");
            }
        } catch (IllegalArgumentException e) {
            System.err.println("错误: " + e.getMessage());
        }
    }
}